package com.leaf.spring.y201911.day15.manager;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import com.leaf.spring.y201911.day15.MyClassLoader;
import com.leaf.spring.y201911.day15.dto.LoadInfo;

public class ManagerFactory {

	/** 记录热加载类的加载信息 */
	private static final Map<String, LoadInfo> loadTimeMap = new HashMap<>();

	/** 要加载的类的 classpath */
	private static final String CLASS_PATH = "D:\\FFT_workspace_jdk8\\workspace_cloud\\library\\spring\\target\\classes\\";

	/** 实现热加载的类的全名称(包名+类名 ) */
	public static final String MY_MANAGER = "com.leaf.spring.y201911.day15.manager.BaseManagerImpl";

	public static BaseManager getManager(String className) {
		
		File file = new File(CLASS_PATH + MY_MANAGER.replace('.', '/') + ".class");
		// 获取最后一次修改时间
		long lastModified = file.lastModified();

		System.out.println(file.getName() + "最后修改时间：" + new Date(lastModified));

		// loadTimeMap 不包含 ClassName 为 key 的信息，证明这个类没有被加载，要加载到 JVM
//		if (!loadTimeMap.containsKey(className)) {
//			load(className, lastModified);
//		} else
//		// 加载类的时间戳变化了，我们同样要重新加载这个类到 JVM。
//		if (loadTimeMap.get(className).getLoadTime() != lastModified) {
//			load(className, lastModified);
//		}
		
		load(className, lastModified);

		return loadTimeMap.get(className).getBaseManager();
	}

	// 加载 class ，缓存到 loadTimeMap
	private static void load(String className, long lastModified) {

		MyClassLoader myClassLoader = new MyClassLoader(className);

		Class<?> loadClass;
		try {

			loadClass = myClassLoader.loadClass(className);
			BaseManager baseManager = (BaseManager) loadClass.newInstance();
			
			LoadInfo loadInfo = new LoadInfo(myClassLoader, lastModified);
			loadInfo.setBaseManager(baseManager);

			loadTimeMap.put(className, loadInfo);

		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

}
